package cn.mes.module.mes.utils.device;

import cn.mes.framework.common.util.object.BeanUtils;
import cn.mes.module.mes.controller.admin.basemachineinfo.vo.apiresponslist.ApiResponseList;
import cn.mes.module.mes.controller.admin.basemachineinfo.vo.apiresponslist.Datum;
import cn.mes.module.mes.controller.admin.basemachineinfo.vo.apiresponslist.JSONParam;
import cn.mes.module.mes.controller.admin.baseworkshop.vo.MachineAreaListReqVO;
import cn.mes.module.mes.dal.dataobject.basemachineinfo.BaseDeviceDataDO;
import cn.mes.module.mes.dal.dataobject.basemachineinfo.BaseMachineInfoDO;
import cn.mes.module.mes.dal.dataobject.baseworkshop.BaseMachineAreaDO;
import cn.mes.module.mes.enums.DataEnum;
import cn.mes.module.mes.service.basemachineinfo.BaseMachineInfoService;
import cn.mes.module.mes.service.baseworkshop.BaseWorkShopService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Title: <br>
 * Description: <br>
 * Copyright: Copyright (c) 2024<br>
 * Company: 四川瀚海精密制造有限公司<br>
 *
 * @author youchuang
 * @version 1.0
 * @date 2024-08-29 17:23
 */
@Component
@Log4j2
public class DeviceGetDataUtils {

    @Value("${plc.baseInfo.username}")
    public String userName;
    @Value("${plc.baseInfo.password}")
    private String password;
    @Value("${plc.baseInfo.baseUrl}")
    private String baseUrl;

    @Value("${plc.baseInfo.url.login}")
    private String loginUrl;
    @Value("${plc.baseInfo.url.region}")
    private String regionUrl;

    @Resource
    private BaseWorkShopService baseWorkShopService;

    @Resource
    private BaseMachineInfoService baseMachineInfoService;

    public String getSid() {
        RestTemplate restTemplate = new RestTemplate();
        String url = String.format(baseUrl + loginUrl, userName, password);
//        log.info("Url:{}",url);
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json;charset=UTF-8");
        headers.setContentType(type);
        HttpEntity httpEntity = new HttpEntity<>(headers);
        ResponseEntity<Object> responseEntity = restTemplate.postForEntity(url, httpEntity, Object.class);
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(responseEntity.getBody());
        return jsonObject.getString("data");
    }


    /**
     * 获取所有设备数据
     */
//    @Scheduled(cron = "0/10 * * * * ? ")
//    @Scheduled(fixedDelay = 30000)
    public void getData() {
        List<BaseMachineAreaDO> baseMachineAreaDOList = this.baseWorkShopService.getMachineAreaList(new MachineAreaListReqVO());
        if (CollectionUtils.isEmpty(baseMachineAreaDOList)) {
            return;
        }
        baseMachineAreaDOList.forEach(item -> {
            if (item.getPlcId() != null) {
                this.getDataDetailByRegionId(item.getPlcId());
            }
        });

    }

    /**
     * 根据区域ID获取该区域的所有数据
     *
     * @param regionId 区域ID
     */
    public void getDataDetailByRegionId(String regionId) {
        String sid = this.getSid();
//        System.out.println("Sid:" + sid);
        RestTemplate restTemplate = new RestTemplate();
        String url = baseUrl + regionUrl + regionId;
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json;charset=UTF-8");
        headers.setContentType(type);
        headers.set("__sid", sid);
        HttpEntity httpEntity = new HttpEntity<>(headers);
        ResponseEntity<ApiResponseList> responseEntity = restTemplate.postForEntity(url, httpEntity, ApiResponseList.class);
        ApiResponseList apiResponse = responseEntity.getBody();
        if (apiResponse == null) {
            return;
        }
        if (apiResponse.getCode() == 200) {
            List<Datum> datumList = apiResponse.getData();
            for (Datum datum : datumList) {

                List<JSONParam> jsonParamList = datum.getJsonParams()
                        .stream()
                        .filter(item ->
                                (item.getParamName().equals(DataEnum.MOLD_NUM_FLAG.getName())
                                        || (item.getParamName().equals(DataEnum.SHIFT_NUM_FLAG.getName()))
                                        || (item.getParamName().equals(DataEnum.CYCLE_FLAG.getName())
                                        || (item.getParamName().equals(DataEnum.CYCLE_FLAG1.getName()))))).collect(Collectors.toList());
                JSONParam moldNumParam = jsonParamList.stream().filter(item -> (item.getParamName().equals(DataEnum.MOLD_NUM_FLAG.getName()))).findFirst().orElse(null);
                if (moldNumParam != null) {
                    datum.setMoldNum(moldNumParam.getRealValue());
                }
                JSONParam shiftNumParam = jsonParamList.stream().filter(item -> (item.getParamName().equals(DataEnum.SHIFT_NUM_FLAG.getName()))).findFirst().orElse(null);
                if (shiftNumParam != null) {
                    datum.setShiftNum(shiftNumParam.getRealValue());
                }
                JSONParam cycleParam = jsonParamList.stream()
                        .filter(item -> (item.getParamName()
                                .equals(DataEnum.CYCLE_FLAG.getName()) || item.getParamName().equals(DataEnum.CYCLE_FLAG1.getName()))).findFirst().orElse(null);
                if (cycleParam != null) {
                    datum.setActualCycle((double) cycleParam.getValue());
                }
                String[] strings = datum.getDeviceName().split("#");
                if (strings.length == 2) {
                    datum.setMachineName(strings[0]);
                }
                datum.setCreateTime(datum.getTimestamp());
                long time = datum.getTimestamp();
                Instant instant = Instant.ofEpochMilli(time);
                ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
                LocalDateTime dateTime = zonedDateTime.toLocalDateTime();
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHH");
                String id = formatter.format(dateTime) + datum.getDeviceId() + datum.getMachineName() + datum.getMoldNum();
                log.info("DateTime:{}", formatter.format(dateTime));
                datum.setId(id);
                log.info("id:{}", id);


            }

            List<BaseDeviceDataDO> deviceDataDOList = BeanUtils.toBean(apiResponse.getData(), BaseDeviceDataDO.class);

            boolean result = this.baseMachineInfoService.createBaseDeviceDataBatch(deviceDataDOList);
            if (result) {
                refreshMachineStatus(regionId,deviceDataDOList);
            }
//            log.info("APi:{}",deviceDataDOList);
        }
    }

    /**
     * 通过区域ID与获取的数据更新机台当前状态
     *
     * @param regionId         区域ID
     * @param deviceDataDOList 设备shuju
     */
    public void refreshMachineStatus(String regionId, List<BaseDeviceDataDO> deviceDataDOList) {
        List<BaseMachineInfoDO> baseMachineInfoDOList = this.baseMachineInfoService.getBaseMachineInfoListByRegionId(regionId);
        List<BaseMachineInfoDO> updateMachineInfoDOList = new ArrayList<>();
        baseMachineInfoDOList.forEach(item->{
            BaseDeviceDataDO baseDeviceDataDO = deviceDataDOList.stream().filter(device->device.getDeviceId().equals(item.getMachinePlcId())).findFirst().orElse(null);
            if(baseDeviceDataDO != null) {
                item.setStatus(baseDeviceDataDO.getStatus());
                updateMachineInfoDOList.add(item);
            }
        });
        if(CollectionUtils.isNotEmpty(updateMachineInfoDOList)) {
            this.baseMachineInfoService.updateBaseMachineInfoBatch(updateMachineInfoDOList);
            log.info("更新了：{} 数据",updateMachineInfoDOList.size());
        }

    }

}
